package by.amakarevich.dataaccess.Impl;

import java.util.List;

import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.SingularAttribute;

import org.hibernate.jpa.criteria.OrderImpl;
import org.springframework.stereotype.Repository;

import by.amakarevich.dataaccess.BookingInfoDao;
import by.amakarevich.datamodel.Booking;
import by.amakarevich.datamodel.BookingInfo;
import by.amakarevich.datamodel.BookingInfo_;

@Repository
public class BookingInfoDaoImpl extends AbstractDaoImpl<Long, BookingInfo> implements BookingInfoDao {
	protected BookingInfoDaoImpl(){
		super(BookingInfo.class);
	}
	@Override
	public List<BookingInfo> getAllBookingInfo(){
        CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

        CriteriaQuery<BookingInfo> criteria = cBuilder.createQuery(BookingInfo.class);
        Root<BookingInfo> root = criteria.from(BookingInfo.class);

        criteria.select(root);

        TypedQuery<BookingInfo> query = getEm().createQuery(criteria);
        List<BookingInfo> results = query.getResultList();
        return results;
	}
	
	@Override
    public List<BookingInfo> getAllBookingInfoByBooking(SingularAttribute<BookingInfo, ?> attr, boolean ascending, int startRecord, int pageSize) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

        CriteriaQuery<BookingInfo> criteria = cBuilder.createQuery(BookingInfo.class);
        Root<BookingInfo> root = criteria.from(BookingInfo.class);

        criteria.select(root);
        criteria.orderBy(new OrderImpl(root.get(attr), ascending));

        TypedQuery<BookingInfo> query = getEm().createQuery(criteria);
        query.setFirstResult(startRecord);
        query.setMaxResults(pageSize);

        List<BookingInfo> results = query.getResultList();
        return results;
    }
	

       
	@Override
    public void deleteBookingInfo(Long id) {
        CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

        CriteriaDelete<BookingInfo> root = cBuilder.createCriteriaDelete(BookingInfo.class);
        Root<BookingInfo> criteria = root.from(BookingInfo.class);


        root.where(cBuilder.equal(criteria.get("id"), id));

        getEm().createQuery(root).executeUpdate();
	}
	
	@Override
	public List<BookingInfo> getAllByBooking(Booking booking) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();
		CriteriaQuery<BookingInfo> criteria = cBuilder
				.createQuery(BookingInfo.class);
		Root<BookingInfo> root = criteria.from(BookingInfo.class);

		criteria.select(root);
		root.fetch(BookingInfo_.booking);
		criteria.distinct(true);
		criteria.where(cBuilder.equal(root.get(BookingInfo_.booking),
				booking.getId()));

		TypedQuery<BookingInfo> query = getEm().createQuery(criteria);
		List<BookingInfo> results = query.getResultList();
		return results;
	}
	
	@Override
	public BookingInfo getByBookingInfoId(Long bookingInfoId) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();
		CriteriaQuery<BookingInfo> criteria = cBuilder
				.createQuery(BookingInfo.class);
		Root<BookingInfo> root = criteria.from(BookingInfo.class);

		criteria.select(root);
		root.fetch(BookingInfo_.product);
		criteria.distinct(true);
		criteria.where(cBuilder.equal(root.get(BookingInfo_.id),
				bookingInfoId));

		TypedQuery<BookingInfo> query = getEm().createQuery(criteria);
		BookingInfo result = (BookingInfo) query.getSingleResult();
		return result;
	}
}
